//
//  JKPresentationManager.swift
//  JKWeibo
//
//  Created by albert on 16/5/13.
//  Copyright © 2016年 albert. All rights reserved.
//  管理自定义popover菜单 转场动画

import UIKit

class JKPresentationManager: NSObject, UIViewControllerTransitioningDelegate {
    
    /** 定义标记 记录当前是否展现 */
    private var isPresent = false
    
    /** 保存菜单的尺寸 */
    var presentFrame = CGRectZero
    
    // 该方法返回一个负责转场动画的对象
    func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController?{
        
        // 这是自定义的JKPresentationController
        let pc = JKPresentationController(presentedViewController: presented, presentingViewController: presenting)
        pc.presentFrame = presentFrame
        return pc
    }
    
    // 该方法用于返回一个负责转场如何出现的对象
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?{
        
        isPresent = true
        // 发出一个通知，告诉调用者状态发生了改变
        NSNotificationCenter.defaultCenter().postNotificationName(JKPresentationManagerDidPresentControllerNotification, object: nil)
        
        //self要遵守UIViewControllerAnimatedTransitioning协议，并实现对应方法
        return self
    }
    
    // 该方法用于返回一个负责转场如何消失的对象
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{
        
        isPresent = false
        // 发出一个通知，告诉调用者状态发生了改变
        NSNotificationCenter.defaultCenter().postNotificationName(JKPresentationManagerDidDismissControllerNotification, object: nil)
        
        //self要遵守UIViewControllerAnimatedTransitioning协议，并实现对应方法
        return self
    }
}

extension JKPresentationManager: UIViewControllerAnimatedTransitioning {
    
    // 告诉系统展现和消失的动画时长。在这里统一控制动画时长
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval{
        
        return 0.25
    }
    
    // 专门用于管理modal如何展现和消失的，无论是展现还是消失都会调用该方法
    func animateTransition(transitionContext: UIViewControllerContextTransitioning){
        
        // 0.判断当前是展现还是消失
        // 注意：消失的时候，toView和fromView已经对换了
        if isPresent {// 展现
            willPresentController(transitionContext)
            
        }else {//消失
            willDismissController(transitionContext)
        }
    }
    
    //MARK: - 执行展现的动画
    private func willPresentController(transitionContext: UIViewControllerContextTransitioning){
        // 1.获取要弹出的视图
        // 通过ToViewKey取出来的就是toVc对应的view
        guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else{
            return
        }
        
        // 2.将需要弹出的视图添加到containerView上
        transitionContext.containerView()?.addSubview(toView)
        
        // 3.执行动画
        toView.transform = CGAffineTransformMakeScale(1, 0)
        
        // 默认动画是从中间慢慢放大的，这是因为图层默认的锚点是(0.5，0.5)
        toView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
        
        UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
            toView.transform = CGAffineTransformIdentity
            
            }) { (_) -> Void in //下划线表示不关心这个
                // 注意：自定义转场动画，在执行完动画之后一定要告诉系统动画执行完毕了！！
                transitionContext.completeTransition(true)
        }
    }
    
    //MARK: - 执行消失的动画
    private func willDismissController(transitionContext: UIViewControllerContextTransitioning){
        guard let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else{
            return
        }
        UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
            // 突然消失的原因：CGFloat不准确，导致无法执行动画，遇到这样的问题将其设置为一个很小的数即可
            fromView.transform = CGAffineTransformMakeScale(1, 0.0001)
            
            }, completion: { (_) -> Void in
                // 注意：自定义转场动画，在执行完动画之后一定要告诉系统动画执行完毕了！！
                transitionContext.completeTransition(true)
        })
    }
}

